/*
 * @(#)MainRequestProcessor.java
 *
 * Copyright (c) 2003 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */
package com.dcivision.framework;

import java.sql.Connection;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionServlet;
import org.apache.struts.config.ModuleConfig;
import org.apache.struts.tiles.TilesRequestProcessor;

import com.dcivision.framework.dao.SysParameterDAObject;
import com.dcivision.framework.web.AbstractAction;
import com.dcivision.user.bean.UserRecord;
import com.dcivision.workflow.applet.net.SystemParameterConstant;

/**
  MainRequestProcessor.java

  This class is the controller which act as the main request processor to handle
  all request and set the default character encoding for all requests.

    @author          Rollo Chan
    @company         DCIVision Limited
    @creation date   24/06/2003
    @version         $Revision: 1.105.2.15 $
*/

public class MainRequestProcessor extends TilesRequestProcessor {

  public static final String REVISION = "$Revision: 1.105.2.15 $";

  protected ApplicationContainer appContainer = null;

  /**
   * Constructor
   */
  public MainRequestProcessor() {
    super();
  }

  /**
   * init
   *
   * @param servlet             ActionServlet object
   * @param moduleConfig        ModuleConfig object
   * @throws ServletException   Servlet exception
   */
  public synchronized void init(ActionServlet servlet, ModuleConfig moduleConfig) throws ServletException {
    synchronized (this) {
      super.init(servlet, moduleConfig);
    }
  }


  /**
   * processPreprocess
   *
   * @param request   HTTP request
   * @param response  HTTP response
   * @return          Whether can process or not.
   */
  protected boolean processPreprocess(HttpServletRequest request, HttpServletResponse response) {
    if (request.getSession().getServletContext().getAttribute(GlobalConstant.CONTEXT_PATH_KEY) == null) {
      request.getSession().getServletContext().setAttribute(GlobalConstant.CONTEXT_PATH_KEY, request.getContextPath());
    }
    if (Utility.isEmpty(SystemParameterFactory.getSystemParameter(SystemParameterConstant.APPLICATION_BASE_URL))
        || !SystemParameterFactory.getSystemParameter(SystemParameterConstant.APPLICATION_BASE_URL).endsWith(request.getContextPath())) {
      String appBaseURL = request.getRequestURL().substring(0, request.getRequestURL().indexOf(request.getContextPath()))
          + request.getContextPath();
      log.info("Initialize Application URL: " + appBaseURL);
      SystemParameterFactory.setSystemParameter(SystemParameterConstant.APPLICATION_BASE_URL, appBaseURL);
      com.dcivision.framework.bean.SysParameter sysPara = new com.dcivision.framework.bean.SysParameter();
      sysPara.setID(new Integer(0));
      sysPara.setParameterCode(SystemParameterConstant.APPLICATION_BASE_URL);
      sysPara.setParameterType("S");
      sysPara.setDescription("The full application URL.");
      sysPara.setParameterValue(appBaseURL);
      Connection conn = null;
      try {
        conn = DataSourceFactory.getConnection();
        SysParameterDAObject sysParaDAO = new SysParameterDAObject((SessionContainer) request.getSession().getAttribute(
            GlobalConstant.SESSION_CONTAINER_KEY), conn);
        sysParaDAO.deleteAppBaseUrl(sysPara);
        sysParaDAO.insertAppBaseUrl(sysPara);
        conn.commit();
      } catch (Exception e) {
        log.error("Error when setting Application Path.", e);
      } finally {
        try {
          conn.close();
        } catch (Exception ignore) {
        } finally {
          conn = null;
        }
      }
    }

    request.setAttribute("originalAction", request.getRequestURL()
        + (Utility.isEmpty(request.getQueryString()) ? "" : ("?" + request.getQueryString())));
    // Check whether the session has login or not.
    return (isLogin(request, response));
  }

  /**
   * isLogin
   *
   * @return          Whether the session is login or not.
   */
  protected boolean isLogin(HttpServletRequest request, HttpServletResponse response) {
    if (((SessionContainer)request.getSession().getAttribute(GlobalConstant.SESSION_CONTAINER_KEY))!=null
            && ((SessionContainer)request.getSession().getAttribute(GlobalConstant.SESSION_CONTAINER_KEY)).getUserRecord()!=null) {
    return(true);
  } else if (request.getRequestURI().length() - request.getRequestURI().lastIndexOf("Index.do")==8) {
    return(true);
    } else if (request.getRequestURI().length() - request.getRequestURI().lastIndexOf("Login.do")==8) {
    return(true);
  }
  /*
   * Update Code Start
   * Author			Jim.Zhou
   * Date			2006/04/24
   * Bug			#4482
   */
  else if (request.getRequestURI().length() - request.getRequestURI().lastIndexOf("Logout.do") == 9){
    try{
    String redirectPath = request.getContextPath() + "/Login.do";
    response.sendRedirect(redirectPath);
  } catch (java.io.IOException ioe){
    log.error("Cannot redirect to login page.", ioe);
  }
  return(false);
  /*
   * Update Code End
   */
  } else if (request.getRequestURI().length() - request.getRequestURI().lastIndexOf("ScanDmsDocument.do")==18) {
    return(true);
  } else if (com.dcivision.customize.CustomizedURIValidator.checkURI(request.getRequestURI())) {
    return(true);
  } else if ("POST".equals(request.getMethod())) {
    try {
      String redirectPath = request.getContextPath() + "/Login.do?action=expire";
      response.sendRedirect(redirectPath);
    } catch (java.io.IOException ioe) {
      log.error("Cannot redirect to login page.", ioe);
    }
    return(false);
  } else {
      try
      {
      String originalPath = request.getRequestURL().toString() + (com.dcivision.framework.Utility.isEmpty(request.getQueryString())?"":("?"+request.getQueryString()));
      if (originalPath.indexOf("opMode=" + GlobalConstant.OP_MODE_LIST_RETAIN) > 0) {
        originalPath = "";
      } else if (originalPath.indexOf("&isLogin=Y") > 0) {
        originalPath = TextUtility.replaceString(originalPath, "&isLogin=Y", "");
      } else if (originalPath.indexOf("?isLogin=Y") > 0) {
        originalPath = TextUtility.replaceString(originalPath, "?isLogin=Y", "");
      }
      String redirectPath = request.getContextPath() + "/Login.do?action=expire&url=" + java.net.URLEncoder.encode(originalPath, "UTF-8");
      response.sendRedirect(redirectPath);
    } catch (java.io.IOException ioe) {
      log.error("Cannot redirect to login page.", ioe);
    }
    return(false);
  }
}

  /**
   * process
   *
   * @param request   HTTP request
   * @param response  HTTP response
   * @throws java.io.IOException
   * @throws javax.servlet.ServletException
   */
  public void process(HttpServletRequest request, HttpServletResponse response) throws java.io.IOException, javax.servlet.ServletException {
    long startTime = 0;
    try {
      startTime = new java.util.Date().getTime();
      log.info("Real-process Started");
      this.openConnection(request);
      super.process(request, response);
    } catch (javax.servlet.ServletException se) {
      log.error("Servlet Exception occurred", se);
      throw se;
    } catch (java.io.IOException ioe) {
      log.error("I/O Exception occurred", ioe);
      throw ioe;
    } finally {
      this.closeConnection(request);
      try { ((com.dcivision.framework.dao.AbstractDAObject)request.getAttribute(GlobalConstant.DAO_KEY)).finalize(); } catch (java.lang.Throwable ignore) {}
      try { request.removeAttribute(GlobalConstant.DAO_KEY); } catch (Exception ignore) {}
      log.info("Real-process Ended - " + (new java.util.Date().getTime() - startTime) + "ms");
    }
  }

  /**
   * processActionPerform
   *
   * @param request    HTTP request
   * @param response   HTTP response
   * @param action     The struts action
   * @param form       The action form
   * @param mapping    The action mapping
   * @return           The action forward
   * @throws java.io.IOExceptions
   * @throws ServletException
   */
  protected ActionForward processActionPerform(HttpServletRequest request, HttpServletResponse response, Action action, ActionForm form, ActionMapping mapping) throws java.io.IOException, ServletException {
    
    ActionForward actionForward = super.processActionPerform(request, response, action, form, mapping);
    ActionForm expectForm = null;
    if (AbstractAction.class.isAssignableFrom(action.getClass())) {
    	if(!Utility.isEmpty(mapping.getAttribute())){
    		expectForm = (ActionForm) request.getAttribute(mapping.getAttribute());
    	}else{
    		expectForm = form;
    	}
     
      ((AbstractAction) action).setPageTitle(request, response, expectForm, mapping, actionForward);
    }
    return actionForward;
  }

  /**
   * processLocale
   *
   * @param request   HTTP request
   * @param response  HTTP response
   */
  protected void processLocale(HttpServletRequest request, HttpServletResponse response) {
    // Set the default encoding.
    this.setDefaultEncoding(request, response);
    // Change the locale if requested.
    if (request.getParameter(GlobalConstant.LANGUAGE_PARAMETER) != null) {
      try {
        java.util.Locale newLocale = Utility.getLocaleByString(request.getParameter(GlobalConstant.LANGUAGE_PARAMETER));
        request.getSession().setAttribute(org.apache.struts.Globals.LOCALE_KEY, newLocale);
        log.info("Locale Updated to " + newLocale);
      } catch (Exception ignore) {
        log.error("Error When Update Locale.", ignore);
      }
    }

    if (request.getSession().getAttribute(org.apache.struts.Globals.LOCALE_KEY)==null) {
      request.getSession().setAttribute(org.apache.struts.Globals.LOCALE_KEY, Utility.getLocaleByString(SystemParameterFactory.getSystemParameter(SystemParameterConstant.LOCALE)));
    }

    //set the language info to cookie
    Cookie cookie = new Cookie(GlobalConstant.LANGUAGE_PARAMETER,request.getSession().getAttribute(org.apache.struts.Globals.LOCALE_KEY).toString());
    //set the life of cookie is 10 year
    cookie.setMaxAge(10*365*24*60*60);
    response.addCookie(cookie);

    //set the preference to cookie
    SessionContainer sessionCon= (SessionContainer)request.getSession().getAttribute(GlobalConstant.SESSION_CONTAINER_KEY);
    if(sessionCon!=null){
      UserRecord userRecord = sessionCon.getUserRecord();
      if(userRecord!=null){
        if(userRecord.getPreference()!=null){
          Cookie preCookie = new Cookie(GlobalConstant.PERSONAL_PREFERENCE,userRecord.getPreference().toString());
          response.addCookie(preCookie);
        }
      }
    }

    super.processLocale(request, response);
  }

  /**
   * setDefaultEncoding
   *
   * Set the Default Encoding for the whole application.
   *
   * @param request   HTTP request
   * @param response  HTTP response
   */
  protected void setDefaultEncoding(HttpServletRequest request, HttpServletResponse response) {
    String encoding = SystemParameterFactory.getSystemParameter(SystemParameterConstant.ENCODING);
    String requestURL=(request.getRequestURL()==null?"":request.getRequestURL().toString());
    if(requestURL.indexOf("form/GenerateXML.do")>0){
      encoding="GBK";
    }
    try {
      if (encoding != null) {
        if (request instanceof org.apache.struts.upload.MultipartRequestWrapper) {
          ((org.apache.struts.upload.MultipartRequestWrapper)request).getRequest().setCharacterEncoding(encoding);
        } else {
          request.setCharacterEncoding(encoding);
        }
      }
    } catch (Exception e) {
      log.error("Unable To Set Character Encoding for \"" + encoding + "\"", e);
    }
  }

  /**
   * openConnection
   *
   * @param request HTTP request
   * @throws ApplicationException
   */
  protected void openConnection(HttpServletRequest request) throws ApplicationException {
    java.sql.Connection conn = null;

    try {
      conn = DataSourceFactory.getConnection();
      request.setAttribute(GlobalConstant.DB_KEY, conn);
      log.info("Get Connection Succeed");
    } catch (Exception e) {
      log.error("Get Connection Error", e);
      try { conn.close(); } catch (Exception ignore) {} finally { conn = null; }
      throw new ApplicationException(ErrorConstant.DB_GET_CONN_ERROR, e);
    }
  }

  /**
   * closeConnection
   *
   * @param request  HTTP request
   * @throws ApplicationException
   */
  protected void closeConnection(HttpServletRequest request) throws ApplicationException {
    java.sql.Connection conn = (java.sql.Connection)request.getAttribute(GlobalConstant.DB_KEY);
    try { request.removeAttribute(GlobalConstant.DB_KEY); } catch (Exception ignore) {}
    try { conn.close(); } catch (Exception ignore) {} finally { conn = null; }
    log.info("Close Connection Succeed");
  }


  /**
   *  destroy
   */
  public void destroy() {
    super.destroy();
    }
    }
